package com.Yukiha.gachamod.command;

import com.Yukiha.gachamod.Data.GachaSavedData;
import com.Yukiha.gachamod.Data.ModelInfoManager;
import com.Yukiha.gachamod.ysm.YsmAuthorizationHandler;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.*;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;

import java.util.*;

public class GachaCommands {

    private static final int MODELS_PER_PAGE = 5;

    public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
        dispatcher.register(
                Commands.literal("gacha")

                        // /gacha list
                        .then(Commands.literal("list")
                                .executes(ctx -> {
                                    ServerPlayer player = ctx.getSource().getPlayerOrException();
                                    return showList(ctx.getSource(), player.getUUID(), player.getName().getString(), 1);
                                })
                                .then(Commands.argument("playerName", StringArgumentType.word())
                                        .suggests((ctx, builder) -> {
                                            List<String> names = ctx.getSource().getServer()
                                                    .getPlayerList()
                                                    .getPlayers()
                                                    .stream()
                                                    .map(player -> player.getGameProfile().getName())
                                                    .toList();

                                            return SharedSuggestionProvider.suggest(names, builder);
                                        })
                                        .executes(ctx -> {
                                            String name = StringArgumentType.getString(ctx, "playerName");
                                            return showListByName(ctx.getSource(), name, 1);
                                        })
                                        .then(Commands.argument("page", IntegerArgumentType.integer(1))
                                                .executes(ctx -> {
                                                    String name = StringArgumentType.getString(ctx, "playerName");
                                                    int page = IntegerArgumentType.getInteger(ctx, "page");
                                                    return showListByName(ctx.getSource(), name, page);
                                                })
                                        )
                                )
                        )

                        // /gacha reload
                        .then(Commands.literal("reload")
                                .requires(src -> src.hasPermission(2))
                                .executes(ctx -> {
                                    ModelInfoManager.reload();
                                    ctx.getSource().sendSystemMessage(Component.literal("§a模型数据已重新加载。"));
                                    return 1;
                                })
                        )

                        // /gacha clear <playerName> <modelId>
                        .then(Commands.literal("clear")
                                .then(Commands.argument("playerName", StringArgumentType.word())
                                        .suggests((ctx, builder) -> {
                                            List<String> names = ctx.getSource().getServer()
                                                    .getPlayerList()
                                                    .getPlayers()
                                                    .stream()
                                                    .map(player -> player.getGameProfile().getName())
                                                    .toList();


                                            return SharedSuggestionProvider.suggest(names, builder);
                                        })
                                        .then(Commands.argument("modelId", StringArgumentType.greedyString())
                                                .suggests((ctx, builder) -> {
                                                    // 模型 ID 补全（来自 ModelInfoManager）
                                                    return SharedSuggestionProvider.suggest(
                                                            com.Yukiha.gachamod.Data.ModelInfoManager.getAllIds(), builder
                                                    );
                                                })
                                                .executes(ctx -> {
                                                    String name = StringArgumentType.getString(ctx, "playerName");
                                                    String modelId = StringArgumentType.getString(ctx, "modelId");

                                                    ServerLevel level = ctx.getSource().getLevel();
                                                    GameProfile profile = level.getServer().getProfileCache().get(name).orElse(null);
                                                    if (profile == null) {
                                                        ctx.getSource().sendFailure(Component.literal("找不到玩家：" + name));
                                                        return 0;
                                                    }

                                                    if (!ModelInfoManager.containsModel(modelId)) {
                                                        ctx.getSource().sendFailure(Component.literal("模型ID无效：" + modelId));
                                                        return 0;
                                                    }

                                                    UUID uuid = profile.getId();
                                                    YsmAuthorizationHandler.unauthorize(uuid, modelId);
                                                    ctx.getSource().sendSuccess(() -> Component.literal("已移除 " + name + " 的模型授权：" + modelId), true);
                                                    return 1;
                                                })
                                        )
                                )
                        )
        );
    }

    private static int showListByName(CommandSourceStack source, String playerName, int page) {
        GameProfile profile = source.getServer().getProfileCache().get(playerName).orElse(null);
        if (profile == null) {
            source.sendSystemMessage(Component.literal("§c未找到玩家 '" + playerName + "' 的历史记录。"));
            return 0;
        }
        return showList(source, profile.getId(), playerName, page);
    }

    private static int showList(CommandSourceStack source, UUID uuid, String playerName, int page) {
        ServerLevel level = source.getLevel();
        Set<String> models = GachaSavedData.get(level).getModels(uuid);
        List<String> sortedModels = models.stream().sorted().toList();

        int total = sortedModels.size();
        int totalPages = Math.max(1, (int) Math.ceil(total / (double) MODELS_PER_PAGE));
        page = Math.min(page, totalPages);

        int start = (page - 1) * MODELS_PER_PAGE;
        int end = Math.min(start + MODELS_PER_PAGE, total);

        source.sendSystemMessage(Component.literal("§a[抽卡记录] 玩家 §f" + playerName + " §a已获得模型：§7(" + page + "/" + totalPages + ")"));

        for (int i = start; i < end; i++) {
            String modelId = sortedModels.get(i);
            ModelInfoManager.ModelInfo info = ModelInfoManager.get(modelId);

            TextColor color = switch (info.rarity().toLowerCase()) {
                case "legendary" -> TextColor.fromRgb(0xFFD700);
                case "epic" -> TextColor.fromRgb(0xAA00FF);
                case "rare" -> TextColor.fromRgb(0x0099FF);
                default -> TextColor.fromRgb(0xAAAAAA);
            };

            Component line = Component.literal(" - ")
                    .append(Component.literal(info.name())
                            .withStyle(Style.EMPTY
                                    .withColor(color)
                                    .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal(info.description())))
                            )
                    );

            source.sendSystemMessage(line);
        }

        if (totalPages > 1) {
            final int currentPage = page;
            final String currentPlayer = playerName;

            MutableComponent nav = Component.literal("");

            if (currentPage > 1) {
                nav.append(Component.literal("[上一页]")
                        .withStyle(style -> style
                                .withColor(TextColor.fromRgb(0x00FFFF))
                                .withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/gacha list " + currentPlayer + " " + (currentPage - 1)))
                                .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("上一页")))
                        )
                ).append(" ");
            }

            if (currentPage < totalPages) {
                nav.append(Component.literal("[下一页]")
                        .withStyle(style -> style
                                .withColor(TextColor.fromRgb(0x00FFFF))
                                .withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/gacha list " + currentPlayer + " " + (currentPage + 1)))
                                .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("下一页")))
                        )
                );
            }

            source.sendSystemMessage(nav);
        }

        return total;
    }
}
